package ru.firststeps.speedtest;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.location.*;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.util.List;
import java.util.Locale;

public class SpeedTestActivity extends Activity implements LocationListener {

    private static final int IDD_PROGRESS = 0;
    private TextView speedTextView;
    private static final String TAG = "SpeedTestActivity";
    private Location currentLocation;
    private LocationManager lm;
    private TextView locationTextView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        final Button button = (Button) findViewById(R.id.measure_button);
        speedTextView = (TextView) findViewById(R.id.speed_text);
        locationTextView = (TextView) findViewById(R.id.location_text);

        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                speedTextView.setVisibility(TextView.INVISIBLE);
                showDialog(IDD_PROGRESS);
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        lm.removeUpdates(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.exit_item:
                finish();
                break;
            case R.id.view_db:
                Intent intent = new Intent();
                intent.setClass(this, ViewDBActivity.class);
                startActivity(intent);
                break;
        }
        return super.onMenuItemSelected(featureId, item);
    }

    @Override
    protected void onResume() {
        super.onResume();
        String provider = null;
        if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
            provider = LocationManager.GPS_PROVIDER;
        }
        if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
                    this);
            if (provider == null) {
                provider = LocationManager.NETWORK_PROVIDER;
            }
        }
        currentLocation = lm.getLastKnownLocation(provider);
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        switch (id) {
            case IDD_PROGRESS:
                Thread thread = new SpeedMeasure(handler);
                thread.start();
                break;
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case IDD_PROGRESS:
                ProgressDialog progressDialog = new ProgressDialog(SpeedTestActivity.this);
                progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                progressDialog.setMessage("Measuring. Please wait ... ");
                progressDialog.setCancelable(false);
                return progressDialog;
            default:
                return null;
        }
    }

    private final Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            dismissDialog(IDD_PROGRESS);
            if (msg.getData().getString("Error") != null) {
                Log.d(TAG, "in if");
                String errorStr = msg.getData().getString("Error");
                speedTextView.setText(getString(R.string.error) + "\""
                        + errorStr + "\"");
            } else {

                ContentValues values = new ContentValues(3);

                 int i;
                double speed = msg.getData().getDouble("Speed");
                for (i = 0; speed >= 1024; i++) {
                    speed /= 1024;
                }
                speed = Math.round(speed * 100) / 100d;
                String[] dimensionArray = getResources().getStringArray(
                        R.array.dimension_array);
                String speedText = speed + dimensionArray[i];
                speedTextView.setText(getString(R.string.speed_text) + speedText);

                values.put(DataDBHelper.SPEED, speedText);

                if (currentLocation != null) {
                    values.put(DataDBHelper.LATITUDE, currentLocation
                            .getLatitude());
                    values.put(DataDBHelper.LONGITUDE, currentLocation
                            .getLongitude());
                }

                ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo ni = cm.getActiveNetworkInfo();
                int netType = ni.getType();
                if (netType == ConnectivityManager.TYPE_WIFI) {
                    WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                    values.put(DataDBHelper.CONNECTION_TYPE, "WiFi");
                    values.put(DataDBHelper.OPERATOR, wm.getConnectionInfo().getSSID());
                } else {
                    TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                    String connectionType;
                    switch (tm.getNetworkType()) {

                        case TelephonyManager.NETWORK_TYPE_UMTS:
                            connectionType = "UMTS";
                            break;
                        case TelephonyManager.NETWORK_TYPE_GPRS:
                            connectionType = "GPRS";
                            break;
                        case TelephonyManager.NETWORK_TYPE_EDGE:
                            connectionType = "EDGE";
                            break;
                        default:
                            connectionType = "Other";
                            break;
                    }
                    values.put(DataDBHelper.CONNECTION_TYPE, connectionType);
                    values.put(DataDBHelper.OPERATOR, tm.getNetworkOperatorName());
                }

                Uri rowid = getContentResolver().insert(DataProvider.CONTENT_URI, values);
                if(rowid == null){
                    Log.d(TAG, "Insert error");
                }
            }
            speedTextView.setVisibility(TextView.VISIBLE);

        }
    };

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onLocationChanged(Location location) {
        if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
            Log.d(TAG, "provider test passed");
        }
        if (location.getProvider().equals(LocationManager.GPS_PROVIDER)
                || (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER) && (currentLocation == null || currentLocation
                .getTime() < location.getTime()))) {

            currentLocation = location;
            double latitude = currentLocation.getLatitude();
            double longitude = currentLocation.getLongitude();
            Log.d(TAG, "Location is not null");
            Geocoder geocoder = new Geocoder(getApplicationContext(), Locale
                    .getDefault());
            String str = null;
            try {
                List<Address> locationList = geocoder.getFromLocation(latitude,
                        longitude, 1);
                if (!locationList.isEmpty()) {
                    Address address = locationList.get(0);
                    for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                        String addressLine = address.getAddressLine(i);
                        if (addressLine.length() == 0)
                            continue;
                        if (i > 0) {
                            str += ", " + addressLine;
                        } else {
                            str = addressLine;
                        }
                    }
                } else {
                    str = getString(R.string.no_address) + latitude + ", "
                            + longitude;
                }
                locationTextView.setText(getString(R.string.location_header)
                        + str);
                locationTextView.setVisibility(TextView.VISIBLE);
            } catch (IOException e) {
                Log.e(TAG, "Location IOException: ", e);
            }

        }
    }
}